package com.packagetracker.views;

import java.util.LinkedList;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.packagetracker.R;
import com.packagetracker.carriers.PackageActivity;
import com.packagetracker.carriers.PackageLocation;
import com.packagetracker.carriers.handlers.PackageHandler;
import com.packagetracker.custom.CustomImageButton;
import com.packagetracker.entities.Carrier;
import com.packagetracker.entities.Settings;
import com.packagetracker.entities.TrackingNumber;
import com.packagetracker.helpers.NumbersHelper;
import com.packagetracker.helpers.SettingsHelper;
import com.packagetracker.providers.TrackerProviderSetup;
import com.packagetracker.utils.MapUtil;
import com.packagetracker.views.overlays.TrackerOverlay;

public class TrackerMap extends MapActivity {
	
	private MapView view;
	private PackageActivity packageActivity;
	private ProgressDialog searchDialog;
	private String number;
	
	public static final int MENU_GOBACK = 0;
	public static final int DIALOG_SEARCH = 0;
	
	@Override
	public void onCreate(final Bundle bundle) {
		super.onCreate(bundle);
		
		this.setContentView(R.layout.map_view);
		this.view = (MapView)this.findViewById(R.id.map_view);
		this.number = this.getIntent().getStringExtra(TrackerProviderSetup.Numbers.NUMBER);
		this.startSearch(this.number);
		this.loadControls();
	}
	
	@Override
	public boolean onCreateOptionsMenu(final Menu menu) {
		super.onCreateOptionsMenu(menu);
		menu.add(0, MENU_GOBACK, Menu.FIRST, R.string.go_back_label).setIcon(R.drawable.menu_goback);
		
		return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(final MenuItem item) {
		super.onOptionsItemSelected(item);
		
		switch (item.getItemId()) {
			case MENU_GOBACK:
				this.finish();
				break;
		}
		
		return true;
	}
	
	@Override
	public boolean onKeyDown(final int key, final KeyEvent event) {
		return MapUtil.keyEvents(this, key, event);
	}
	
	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}
	
	public MapView getView() {
		return this.view;
	}
	
	private void loadControls() {
		final CustomImageButton map = (CustomImageButton)this.findViewById(R.id.map_toggle_map);
		map.setOnClickListener(new View.OnClickListener() {
			public void onClick(final View view) {
				final ContentValues values = new ContentValues();
				values.put(TrackerProviderSetup.Settings.MAP_TYPE, Settings.TYPE_MAP);
				new SettingsHelper(TrackerMap.this).update(values);
				MapUtil.toggleSatellite(TrackerMap.this.getView(), Settings.TYPE_MAP);
			}
		});
		
		final CustomImageButton satellite = (CustomImageButton)this.findViewById(R.id.map_toggle_satellite);
		satellite.setOnClickListener(new View.OnClickListener() {
			public void onClick(final View view) {
				final ContentValues values = new ContentValues();
				values.put(TrackerProviderSetup.Settings.MAP_TYPE, Settings.TYPE_SATELLITE);
				new SettingsHelper(TrackerMap.this).update(values);
				MapUtil.toggleSatellite(TrackerMap.this.getView(), Settings.TYPE_SATELLITE);
			}
		});
		
		//MapUtil.toggleZoomControls(this.getView());
		MapUtil.toggleSatellite(this.getView(), new SettingsHelper(this).getSettings().getMapType());
	}
	
	private Handler showTrackingResults = new Handler() {
		@Override
		public void handleMessage(final Message message) {
			TrackerMap.this.searchDialog.dismiss();
			
			if ((TrackerMap.this.packageActivity != null) && TrackerMap.this.packageActivity.hasLocations()) {
				final LinkedList<PackageLocation> locations = TrackerMap.this.packageActivity.getLocations();
				TrackerMap.this.buildOverlays(locations);
				MapUtil.moveTo(TrackerMap.this.getView(), locations.get(locations.size() - 1), 5);
			}
			else {
				new AlertDialog.Builder(TrackerMap.this)
					.setIcon(R.drawable.icon_warning)
					.setTitle(R.string.error_title)
					.setMessage(R.string.error_message)
					.setPositiveButton(R.string.ok_label, new DialogInterface.OnClickListener() {
						public void onClick(final DialogInterface dialog, final int button) {
							TrackerMap.this.setResult(TrackerMap.RESULT_OK);
							TrackerMap.this.finish();
						}
					})
					.setNegativeButton(R.string.try_again_label, new DialogInterface.OnClickListener() {
						public void onClick(final DialogInterface dialog, final int button) {
							TrackerMap.this.setResult(TrackerMap.RESULT_CANCELED);
							TrackerMap.this.startSearch(TrackerMap.this.number);
						}
					})
					.create()
					.show();
			}
		}
	};
	
	private void startSearch(final String number) {
		this.searchDialog = ProgressDialog.show(this, this.getString(R.string.search_dialog_title), this.getString(R.string.search_dialog_message), true, false);
		
		final Thread searchNumber = new Thread() {
			public void run() {
				try {
					TrackerMap.this.packageActivity = TrackerMap.this.getPackageActivity(number);
					
					Thread.sleep(1500);
				}
				catch (Exception e) {}
				
				TrackerMap.this.showTrackingResults.sendEmptyMessage(0);						
			}
		};
		
		searchNumber.start();
	}
	
	private void buildOverlays(final LinkedList<PackageLocation> locations) {
		this.getView().getOverlays().clear();
		this.getView().getOverlays().add(new TrackerOverlay(this, MapUtil.getMarker(this.view, R.drawable.overlay_blue_dot), locations));
	}
	
	private PackageActivity getPackageActivity(final String trackingNumber) {
		final TrackingNumber number = new NumbersHelper(TrackerMap.this).getNumber(trackingNumber);
		
		final Carrier carrier = new Carrier(number.getCarrier());
		final PackageHandler handler = carrier.getHandler();
		
		if (handler != null) {
			handler.parsePackageActivity(this, trackingNumber);
			
			final PackageActivity activity = handler.getPackageActivity();
			final Geocoder geocoder = new Geocoder(this);
			
			try {
				for (final PackageLocation location : activity.getLocations()) {
					for (final Address address : geocoder.getFromLocationName(location.toString(), 1)) {
						location.setGeoPoint(address.getLatitude(), address.getLongitude());
					}
				}
			}
			catch (Exception e) {}
			
			return activity;
		}
		
		return null;
	}
	
}